<?php

// 测试
// $captcha = new Captcha();
// $captcha->outImage();

// 验证码类
class Captcha
{
    // 验证码个数
    protected $number;
    // 验证码类型
    protected $captchaType;
    // 图像宽度
    protected $width;
    // 图像高度
    protected $height;
    // 图像资源
    protected $image;
    // 验证码字符串
    protected $captcha;

    public function __construct($number = 4, $captchaType = 2, $width = 100, $height = 50)
    {
        // 初始化自己的成员属性
        $this->number = $number;
        $this->captchaType = $captchaType;
        $this->width = $width;
        $this->height = $height;

        // 生成验证码函数
        $this->captcha = $this->ceratecCaptcha();
    }

    public function __destruct()
    {
        imagedestroy($this->image);
    }

    // 获取 验证码 code
    public function __get($name)
    {
        if ($name == 'captcha') {
            return $this->captcha;
        }
        return false;
    }

    // 生成验证码
    protected function ceratecCaptcha()
    {
        // 通过验证码类型生成不同的验证码
        switch ($this->captchaType) {
            case 0: // 纯数字
                $captcha = $this->getNumberCaptcha();
                break;
            case 1: // 纯字母
                $captcha = $this->getCharCaptcha();
                break;
            case 2: // 字母和数字混合
                $captcha = $this->getNumCharCaptcha();
                break;
            default:
                die('不支持这种验证码类型');
                break;
        }
        return $captcha;
    }

    // 获得纯数字验证码
    protected function getNumberCaptcha()
    {
        $str = join('', range(0, 9));
        return substr(str_shuffle($str), 0, $this->number);
    }

    // 获得纯字母验证码
    protected function getCharCaptcha()
    {
        $str = join('', range('a', 'z'));
        $str = $str . strtoupper($str);
        return substr(str_shuffle($str), 0, $this->number);
    }

    // 获得字母和数字混合验证码
    protected function getNumCharCaptcha()
    {
        $str = join('', range('a', 'z'));
        $str = join('', range(0, 9)) . $str . strtoupper($str);
        return substr(str_shuffle($str), 0, $this->number);
    }

    // 输出图片
    public function outImage()
    {
        // 创建画布
        $this->crtateImage();
        // 填充背景色
        $this->setBackgroundColor();
        // 将验证码字符串画到画布中
        $this->drawCaptcha();
        // 添加干扰元素
        $this->drawDisturb();
        // 输出并显示
        $this->show();
    }

    // 创建画布
    protected function crtateImage()
    {
        $this->image = imagecreatetruecolor($this->width, $this->height);
    }

    // 填充背景色
    protected function setBackgroundColor()
    {
        imagefill($this->image, 0, 0, $this->randLightColor());
    }

    // 生成随机浅色
    protected function randLightColor()
    {
        return imagecolorallocate($this->image, mt_rand(130, 255), mt_rand(130, 255), mt_rand(130, 255));
    }

    // 生成随机深色
    protected function randDeepColor()
    {
        return imagecolorallocate($this->image, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
    }

    // 将验证码字符串画到画布中
    protected function drawCaptcha()
    {
        $width = ceil($this->width / $this->number);
        for ($i = 0; $i < $this->number; $i++) {
            $x = mt_rand($i * $width + 5, ($i + 1) * $width - 10);
            $y = mt_rand(0, $this->height - 15);
            imagechar($this->image, 10, $x, $y, $this->captcha[$i], $this->randDeepColor());
        }
    }

    // 添加干扰元素
    protected function drawDisturb()
    {
        for ($i = 0; $i < 150; $i++) {
            $x = mt_rand(0, $this->width);
            $y = mt_rand(0, $this->height);
            imagesetpixel($this->image, $x, $y, $this->randLightColor());
        }
    }

    // 输出并显示
    protected function show()
    {
        header('Content-type:image/png');
        imagepng($this->image);
    }
}
